use crate::ctp_commands::ctp::types::{InstrumentInfo, AccountInfo, PositionInfo, OrderRequest};
use crate::ctp_commands::ctp::state::*;
use crate::audio_manager;
use crate::logger;
use log::{info, warn, error};

/// 订单验证错误类型
#[derive(Debug, Clone, serde::Serialize)]
pub struct ValidationError {
    pub error_type: String,
    pub message: String,
    pub field: Option<String>,
    pub play_sound: bool,
}

impl ValidationError {
    pub fn new(error_type: &str, message: &str, field: Option<&str>, play_sound: bool) -> Self {
        Self {
            error_type: error_type.to_string(),
            message: message.to_string(),
            field: field.map(|s| s.to_string()),
            play_sound,
        }
    }
}

/// 订单验证结果
#[derive(Debug, serde::Serialize)]
pub struct ValidationResult {
    pub is_valid: bool,
    pub errors: Vec<ValidationError>,
}

impl ValidationResult {
    pub fn valid() -> Self {
        Self {
            is_valid: true,
            errors: Vec::new(),
        }
    }

    pub fn invalid(errors: Vec<ValidationError>) -> Self {
        Self {
            is_valid: false,
            errors,
        }
    }

    pub fn add_error(&mut self, error: ValidationError) {
        self.is_valid = false;
        self.errors.push(error);
    }
}

/// 验证合约代码是否有效
pub fn validate_instrument_code(
    instrument_id: &str,
    instrument_info: Option<&InstrumentInfo>,
) -> Result<(), ValidationError> {
    if instrument_id.is_empty() {
        let error = ValidationError::new(
            "INVALID_INSTRUMENT",
            "合约代码不能为空",
            Some("instrument_id"),
            true,
        );
        warn!("❌ [VALIDATION] 合约代码验证失败: {}", error.message);
        logger::log_validation_error("INVALID_INSTRUMENT", "", "合约代码不能为空");
        audio_manager::play_error_notification();
        return Err(error);
    }

    if let Some(info) = instrument_info {
        // 检查合约是否可交易
        if info.is_trading == 0 {
            let error = ValidationError::new(
                "INSTRUMENT_NOT_TRADING",
                &format!("合约 {} 当前不可交易", instrument_id),
                Some("instrument_id"),
                true,
            );
            warn!("❌ [VALIDATION] 合约交易状态验证失败: {} - is_trading={}", instrument_id, info.is_trading);
            logger::log_validation_error("INSTRUMENT_NOT_TRADING", instrument_id, &error.message);
            audio_manager::play_error_notification();
            return Err(error);
        }
    } else {
        let error = ValidationError::new(
            "INSTRUMENT_NOT_FOUND",
            &format!("未找到合约 {} 的信息", instrument_id),
            Some("instrument_id"),
            true,
        );
        warn!("❌ [VALIDATION] 合约信息查询失败: {}", instrument_id);
        logger::log_validation_error("INSTRUMENT_NOT_FOUND", instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    Ok(())
}

/// 验证价格是否符合最小变动价位
pub fn validate_price_tick(
    price: f64,
    instrument_info: &InstrumentInfo,
) -> Result<(), ValidationError> {
    let price_tick = instrument_info.price_tick;
    
    if price_tick <= 0.0 {
        let error = ValidationError::new(
            "INVALID_PRICE_TICK",
            "合约最小变动价位配置错误",
            Some("price"),
            true,
        );
        error!("❌ [VALIDATION] 价格间距配置错误: {} - price_tick={}", instrument_info.instrument_id, price_tick);
        logger::log_validation_error("INVALID_PRICE_TICK_CONFIG", &instrument_info.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    // 计算价格是否是price_tick的整数倍
    let remainder = (price % price_tick).abs();
    let tolerance = price_tick * 0.0001; // 允许浮点误差

    if remainder > tolerance && (price_tick - remainder) > tolerance {
        let error = ValidationError::new(
            "INVALID_PRICE_TICK",
            &format!(
                "价格 {} 不符合最小变动价位 {}，请调整为 {} 的整数倍",
                price, price_tick, price_tick
            ),
            Some("price"),
            true,
        );
        warn!("❌ [VALIDATION] 价格间距验证失败: {} - price={}, price_tick={}, remainder={}", 
            instrument_info.instrument_id, price, price_tick, remainder);
        logger::log_validation_error("INVALID_PRICE_TICK", &instrument_info.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    Ok(())
}

/// 验证委托手数是否在允许范围内
pub fn validate_volume(
    volume: i32,
    instrument_info: &InstrumentInfo,
) -> Result<(), ValidationError> {
    let min_volume = instrument_info.min_limit_order_volume;
    let max_volume = instrument_info.max_limit_order_volume;

    if volume < min_volume {
        let error = ValidationError::new(
            "VOLUME_TOO_SMALL",
            &format!(
                "委托手数 {} 小于最小限制 {}手",
                volume, min_volume
            ),
            Some("volume"),
            true,
        );
        warn!("❌ [VALIDATION] 手数过小: {} - volume={}, min={}", instrument_info.instrument_id, volume, min_volume);
        logger::log_validation_error("VOLUME_TOO_SMALL", &instrument_info.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    if volume > max_volume {
        let error = ValidationError::new(
            "VOLUME_TOO_LARGE",
            &format!(
                "委托手数 {} 超过单笔最大限制 {}手",
                volume, max_volume
            ),
            Some("volume"),
            true,
        );
        warn!("❌ [VALIDATION] 手数过大: {} - volume={}, max={}", instrument_info.instrument_id, volume, max_volume);
        logger::log_validation_error("VOLUME_TOO_LARGE", &instrument_info.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    Ok(())
}

/// 验证账户资金是否足够开仓
pub fn validate_available_funds(
    order: &OrderRequest,
    account_info: &AccountInfo,
    instrument_info: &InstrumentInfo,
) -> Result<(), ValidationError> {
    // 只验证开仓单
    let offset_flag = order.offset_flag.as_deref().unwrap_or("0");
    if offset_flag != "0" {
        // 平仓单不需要验证资金
        return Ok(());
    }

    let available = account_info.available;
    let price = order.price;
    let volume = order.volume as f64;
    let volume_multiple = instrument_info.volume_multiple as f64;

    // 计算所需保证金
    let margin_ratio = if order.direction == "0" {
        // 买入（做多）
        instrument_info.long_margin_ratio
    } else {
        // 卖出（做空）
        instrument_info.short_margin_ratio
    };

    let required_margin = price * volume * volume_multiple * margin_ratio;

    // 预留5%的缓冲空间，防止价格波动导致保证金不足
    let required_margin_with_buffer = required_margin * 1.05;

    if available < required_margin_with_buffer {
        let error = ValidationError::new(
            "INSUFFICIENT_FUNDS",
            &format!(
                "可用资金不足：需要 {:.2} 元（含缓冲），当前可用 {:.2} 元",
                required_margin_with_buffer, available
            ),
            Some("funds"),
            true,
        );
        warn!("❌ [VALIDATION] 资金不足: {} - required={:.2}, available={:.2}, margin_ratio={}", 
            order.instrument_id, required_margin_with_buffer, available, margin_ratio);
        logger::log_validation_error("INSUFFICIENT_FUNDS", &order.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    Ok(())
}

/// 验证平仓时是否有足够的持仓
pub fn validate_close_position(
    order: &OrderRequest,
    positions: &[PositionInfo],
) -> Result<(), ValidationError> {
    // 只验证平仓单
    let offset_flag = order.offset_flag.as_deref().unwrap_or("0");
    if offset_flag == "0" {
        // 开仓单不需要验证持仓
        return Ok(());
    }

    // 查找对应的持仓
    let position = positions.iter().find(|p| {
        p.instrument_id == order.instrument_id
    });

    if let Some(pos) = position {
        // 根据方向判断持仓类型
        // 买入平仓需要空头持仓，卖出平仓需要多头持仓
        let required_direction = if order.direction == "0" {
            "3" // 空头持仓（卖方向）
        } else {
            "2" // 多头持仓（买方向）
        };

        if pos.posi_direction != required_direction {
            let error = ValidationError::new(
                "NO_POSITION_TO_CLOSE",
                &format!(
                    "无可平持仓：尝试{}平仓，但没有对应的{}持仓",
                    if order.direction == "0" { "买入" } else { "卖出" },
                    if order.direction == "0" { "空头" } else { "多头" }
                ),
                Some("position"),
                true,
            );
            warn!("❌ [VALIDATION] 持仓方向不匹配: {} - order_direction={}, position_direction={}", 
                order.instrument_id, order.direction, pos.posi_direction);
            logger::log_validation_error("NO_POSITION_TO_CLOSE", &order.instrument_id, &error.message);
            audio_manager::play_error_notification();
            return Err(error);
        }

        // 检查持仓数量是否足够
        let available_position = pos.position - pos.long_frozen - pos.short_frozen;
        if available_position < order.volume {
            let error = ValidationError::new(
                "INSUFFICIENT_POSITION",
                &format!(
                    "可平持仓不足：需要 {} 手，当前可平 {} 手",
                    order.volume, available_position
                ),
                Some("position"),
                true,
            );
            warn!("❌ [VALIDATION] 持仓数量不足: {} - required={}, available={}, total={}, frozen={}", 
                order.instrument_id, order.volume, available_position, pos.position, pos.long_frozen + pos.short_frozen);
            logger::log_validation_error("INSUFFICIENT_POSITION", &order.instrument_id, &error.message);
            audio_manager::play_error_notification();
            return Err(error);
        }
    } else {
        let error = ValidationError::new(
            "NO_POSITION_TO_CLOSE",
            &format!("合约 {} 无持仓可平", order.instrument_id),
            Some("position"),
            true,
        );
        warn!("❌ [VALIDATION] 无持仓记录: {} - 尝试平仓但未找到持仓", order.instrument_id);
        logger::log_validation_error("NO_POSITION_TO_CLOSE", &order.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    Ok(())
}

/// 验证市场状态是否允许交易
pub fn validate_market_status(
    instrument_info: &InstrumentInfo,
) -> Result<(), ValidationError> {
    // 检查合约是否在交易时段
    if instrument_info.is_trading == 0 {
        let error = ValidationError::new(
            "MARKET_CLOSED",
            &format!("合约 {} 当前不在交易时段", instrument_info.instrument_id),
            None,
            true,
        );
        warn!("❌ [VALIDATION] 市场关闭: {} - is_trading=0", instrument_info.instrument_id);
        logger::log_validation_error("MARKET_CLOSED", &instrument_info.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    // 检查合约生命周期状态
    let life_phase = &instrument_info.inst_life_phase;
    if life_phase != "Started" && life_phase != "NotStart" {
        let error = ValidationError::new(
            "INSTRUMENT_EXPIRED",
            &format!(
                "合约 {} 已过期或即将到期，当前状态: {}",
                instrument_info.instrument_id, life_phase
            ),
            None,
            true,
        );
        warn!("❌ [VALIDATION] 合约过期: {} - life_phase={}", instrument_info.instrument_id, life_phase);
        logger::log_validation_error("INSTRUMENT_EXPIRED", &instrument_info.instrument_id, &error.message);
        audio_manager::play_error_notification();
        return Err(error);
    }

    Ok(())
}

/// 综合验证订单
pub async fn validate_order(
    _session_id: &str,
    order: &OrderRequest,
) -> ValidationResult {
    info!("🔍 [VALIDATION] 开始验证订单: instrument={}, direction={}, price={}, volume={}, offset={}", 
        order.instrument_id, 
        if order.direction == "0" { "买入" } else { "卖出" },
        order.price,
        order.volume,
        order.offset_flag.as_deref().unwrap_or("0")
    );
    
    let mut result = ValidationResult::valid();

    // 1. 获取合约信息
    let instrument_info = {
        let instruments = get_ctp_instruments_data().lock().unwrap();
        instruments.iter()
            .find(|i| i.instrument_id == order.instrument_id)
            .cloned()
    };

    // 2. 验证合约代码
    if let Err(e) = validate_instrument_code(&order.instrument_id, instrument_info.as_ref()) {
        result.add_error(e);
        logger::log_order_validation(&order.instrument_id, false, Some("合约代码验证失败"));
        return result; // 合约无效，直接返回
    }

    let instrument_info = match instrument_info {
        Some(info) => info,
        None => {
            result.add_error(ValidationError::new(
                "INSTRUMENT_NOT_FOUND",
                &format!("未找到合约 {} 的信息，请先查询合约列表", order.instrument_id),
                Some("instrument_id"),
                true,
            ));
            return result;
        }
    };

    // 3. 验证价格最小变动价位
    if let Err(e) = validate_price_tick(order.price, &instrument_info) {
        result.add_error(e);
    }

    // 4. 验证委托手数
    if let Err(e) = validate_volume(order.volume, &instrument_info) {
        result.add_error(e);
    }

    // 5. 验证市场状态
    if let Err(e) = validate_market_status(&instrument_info) {
        result.add_error(e);
    }

    // 6. 获取账户信息并验证资金（仅开仓）
    let offset_flag = order.offset_flag.as_deref().unwrap_or("0");
    if offset_flag == "0" {
        // 查询真实的账户信息
        info!("🔍 开仓单，开始验证资金...");
        
        // 从全局状态获取最新的账户数据
        let account_info_opt = {
            let account_data = get_ctp_account_data().lock().unwrap();
            account_data.clone()
        };
        
        if let Some(account_info) = account_info_opt {
            // 验证资金是否充足
            if let Err(e) = validate_available_funds(order, &account_info, &instrument_info) {
                result.add_error(e);
            }
        } else {
            // 如果没有账户数据，给出警告但不阻止交易
            warn!("⚠️ 未找到账户数据缓存，跳过资金验证。建议先查询账户信息。");
            info!("💡 提示：系统会在首次登录后自动查询账户信息，或手动调用query_account");
        }
    }

    // 7. 获取持仓信息并验证平仓（仅平仓）
    if offset_flag != "0" {
        let positions = {
            let positions_data = get_ctp_positions_data().lock().unwrap();
            positions_data.clone()
        };

        if let Err(e) = validate_close_position(order, &positions) {
            result.add_error(e);
        }
    }

    // 8. 如果有错误，播放提示音并记录日志
    if !result.is_valid {
        error!("❌ [VALIDATION] 订单验证失败: instrument={}, errors={}", 
            order.instrument_id, result.errors.len());
        
        // 记录所有错误到日志
        for (i, err) in result.errors.iter().enumerate() {
            error!("  错误 {}: [{}] {}", i + 1, err.error_type, err.message);
        }
        
        // 记录验证失败日志
        let error_summary = result.errors.iter()
            .map(|e| e.error_type.as_str())
            .collect::<Vec<_>>()
            .join(", ");
        logger::log_order_validation(&order.instrument_id, false, Some(&error_summary));
        
        // 播放错误提示音
        if result.errors.iter().any(|e| e.play_sound) {
            info!("🔊 播放错误提示音");
            audio_manager::play_error_notification();
        }
    } else {
        info!("✅ [VALIDATION] 订单验证通过: instrument={}", order.instrument_id);
        logger::log_order_validation(&order.instrument_id, true, None);
    }

    result
}

